// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FormHelper.cs" company="">
//   
// </copyright>
// <summary>
//   Defines the FormHelper type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ComparisonTool.Connection
{
    using System.Net;
    using System.Windows.Forms;

    using ComparisonTool.Forms;
    using ComparisonTool.Forms.Connection;

    /// <summary>
    /// The form helper.
    /// </summary>
    public class FormHelper
    {
        /// <summary>
        /// The _inner app form.
        /// </summary>
        private readonly Form innerAppForm;

        /// <summary>
        /// The _connection manager.
        /// </summary>
        private readonly ConnectionManager connectionManager;

        /// <summary>
        /// Initializes a new instance of the <see cref="FormHelper"/> class.
        /// </summary>
        /// <param name="innerAppForm">
        /// The inner app form.
        /// </param>
        /// <param name="connectionManager">
        /// The connection manager.
        /// </param>
        public FormHelper(Form innerAppForm, ConnectionManager connectionManager)
        {
            this.innerAppForm = innerAppForm;
            this.connectionManager = connectionManager;
        }

        /// <summary>
        /// Checks the existence of a user password and returns it
        /// </summary>
        /// <param name="detail">
        /// Details of the connection
        /// </param>
        /// <returns>
        /// True if password defined
        /// </returns>
        public bool RequestPassword(ConnectionDetail detail)
        {
            if (!string.IsNullOrEmpty(detail.UserPassword))
            {
                return true;
            }

            var returnValue = false;

            var passwordForm = new PasswordForm
            {
                UserLogin = detail.UserName, 
                UserDomain = detail.UserDomain, 
                StartPosition = FormStartPosition.CenterParent
            };

            MethodInvoker mi = delegate
            {
                if (passwordForm.ShowDialog(this.innerAppForm) == DialogResult.OK)
                {
                    detail.UserPassword = passwordForm.UserPassword;
                    detail.SavePassword = passwordForm.SavePassword;
                    returnValue = true;
                }
            };

            if (this.innerAppForm.InvokeRequired)
            {
                this.innerAppForm.Invoke(mi);
            }
            else
            {
                mi();
            }

            return returnValue;
        }

        /// <summary>
        /// The ask for connection.
        /// </summary>
        /// <param name="connectionParameter">
        /// The connection parameter.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool AskForConnection(object connectionParameter)
        {
            var cs = new ConnectionSelector(this.connectionManager.LoadConnectionsList(), this.connectionManager)
            {
                StartPosition = FormStartPosition.CenterParent, 
                ConnectionList = this.connectionManager.LoadConnectionsList()
            };

            if (cs.ShowDialog(this.innerAppForm) == DialogResult.OK)
            {
                this.connectionManager.ConnectToServer(cs.SelectedConnection, 1, connectionParameter);

                if (cs.HadCreatedNewConnection)
                {
                    this.connectionManager.ConnectionsList.Connections.Add(cs.SelectedConnection);
                    this.connectionManager.SaveConnectionsFile(this.connectionManager.ConnectionsList);
                }

                return true;
            }

            return false;
        }

        /// <summary>
        /// The edit connection.
        /// </summary>
        /// <param name="isCreation">
        /// The is creation.
        /// </param>
        /// <param name="connectionToUpdate">
        /// The connection to update.
        /// </param>
        /// <param name="id">
        /// Guid of organization control.
        /// </param>
        /// <returns>
        /// The <see cref="ConnectionDetail"/>.
        /// </returns>
        public ConnectionDetail EditConnection(bool isCreation, ConnectionDetail connectionToUpdate, int id)
        {
            var connectionForm = new ConnectionForm(isCreation) { StartPosition = FormStartPosition.CenterParent };

            if (!isCreation)
            {
                connectionForm.CrmConnectionDetail = connectionToUpdate;
            }

            if (connectionForm.ShowDialog(this.innerAppForm) == DialogResult.OK)
            {
                if (isCreation)
                {
                    this.connectionManager.ConnectionsList.Connections.Add(connectionForm.CrmConnectionDetail);
                }
                else
                {
                    foreach (var detail in this.connectionManager.ConnectionsList.Connections)
                    {
                        if (detail.ConnectionId == connectionForm.CrmConnectionDetail.ConnectionId)
                        {
                            detail.ConnectionName = connectionForm.CrmConnectionDetail.ConnectionName;
                            detail.OrganizationServiceUrl = connectionForm.CrmConnectionDetail.OrganizationServiceUrl;
                            detail.CrmTicket = connectionForm.CrmConnectionDetail.CrmTicket;
                            detail.IsCustomAuth = connectionForm.CrmConnectionDetail.IsCustomAuth;
                            detail.Organization = connectionForm.CrmConnectionDetail.Organization;
                            detail.OrganizationFriendlyName = connectionForm.CrmConnectionDetail.OrganizationFriendlyName;
                            detail.ServerName = connectionForm.CrmConnectionDetail.ServerName;
                            detail.ServerPort = connectionForm.CrmConnectionDetail.ServerPort;
                            detail.UseIfd = connectionForm.CrmConnectionDetail.UseIfd;
                            detail.UseOnline = connectionForm.CrmConnectionDetail.UseOnline;
                            detail.UseOsdp = connectionForm.CrmConnectionDetail.UseOsdp;
                            detail.UserDomain = connectionForm.CrmConnectionDetail.UserDomain;
                            detail.UserName = connectionForm.CrmConnectionDetail.UserName;
                            detail.UserPassword = connectionForm.CrmConnectionDetail.UserPassword;
                            detail.UseSsl = connectionForm.CrmConnectionDetail.UseSsl;
                            detail.HomeRealmUrl = connectionForm.CrmConnectionDetail.HomeRealmUrl;
                        }
                    }
                }

                if (connectionForm.DoConnect)
                {
                    this.connectionManager.ConnectToServer(connectionForm.CrmConnectionDetail, id);
                }

                this.connectionManager.SaveConnectionsFile(this.connectionManager.ConnectionsList);

                return connectionForm.CrmConnectionDetail;
            }

            return null;
        }

        /// <summary>
        /// The select proxy.
        /// </summary>
        /// <returns>
        /// The <see cref="IWebProxy"/>.
        /// </returns>
        public IWebProxy SelectProxy()
        {
            if (this.connectionManager.ConnectionsList.UseCustomProxy)
            {
                var proxy = new WebProxy(this.connectionManager.ConnectionsList.ProxyAddress + ":" + this.connectionManager.ConnectionsList.ProxyPort, true)
                {
                    Credentials =
                        new NetworkCredential(this.connectionManager.ConnectionsList.UserName, this.connectionManager.ConnectionsList.Password)
                };

                return proxy;
            }

            return null;
        }

        /// <summary>
        /// Deletes a connection from the connections list
        /// </summary>
        /// <param name="connectionToDelete">
        /// Details of the connection to delete
        /// </param>
        /// <param name="id">
        /// </param>
        public void DeleteConnection(ConnectionDetail connectionToDelete, int id)
        {
            this.connectionManager.ConnectionsList.Connections.Remove(connectionToDelete);
            this.connectionManager.SaveConnectionsFile(this.connectionManager.ConnectionsList);
        }
    }
}
